import { Router, RouteRecordRaw } from 'vue-router'
import { cloneDeep } from 'lodash-es'
import { userState } from '~/types/user'
import { getStorage, setStorage } from '@/utils/storage'
import { router } from '@/router/index'
import { basicsRoutes } from '@/router/routes'
import { useTabsStore } from '@/store/modules/tabs'
import defaultDict from '@/config/defaultDict.config'
import { menuModel } from '@/api/model/menuModel'
import { FuncTyp } from '~/types/menu'
import layout from '@/layout/index.vue'
import { treeForEach } from '@/utils/tree'
import { allDelDictDataApi } from '@/api/system/dict'
import { getUserMenuApi } from '@/api/system/menu'
import { Login } from '@/api/model/userModel'
import { menuItem } from '@/api/model/menuModel'
import {
  login,
  refreshToken as refreshToken_,
  logout,
  getUserInfoApi,
  iamLogin
} from '@/api/system/user'

const viewModules = import.meta.glob(['@/views/**/*.{vue,tsx}'])
const token = getStorage('token') ?? ''
const refreshToken = getStorage('refreshToken') ?? ''
const expiresIn = getStorage('expiresIn') ?? 0

export const useUser = defineStore({
  id: 'user',
  state: (): userState => ({
    userInfo: {},
    userMenu: [],
    noDisplayMenu: [],
    userPermi: [],
    cacheList: [],
    dict: [],
    oauth: {
      userId: null,
      token,
      refreshToken,
      expiresIn
    }
  }),
  getters: {
    dictMap: (state) => {
      const data = {}
      const dict = [...defaultDict, ...state.dict]
      dict.forEach((item) => {
        data[item.type] = item.children
      })
      return data
    }
  },
  actions: {
    //登录
    async login(data: Login) {
      const res = await login(data)
      if (res.code === '0000') {
        this.setOauth(res.data)
      }
      return res.code
    },
    async iamLogin(data) {
      const res = await iamLogin(data)
      if (res.code === '0000') {
        this.setOauth(res.data)
      }
      return res.code
    },
    //刷新token
    async refreshToken() {
      // @Todo: 暂时去掉刷新token
      // const res = await refreshToken_({ refreshToken: this.oauth.refreshToken })
      // if (res.code === '0000') {
      //   this.setOauth(res.data)
      //   return true
      // } else return false
      return false
    },
    //设置用户信息
    setUserInfo(this, data) {
      this.userInfo = data
    },
    delCache(this, name) {
      if (!name) return
      this.cacheList = this.cacheList.filter((v) => v !== name)
    },
    addCache(this, name) {
      if (!name) return
      this.cacheList = Array.from(new Set([...this.cacheList, name]))
      console.log(this.cacheList)
    },
    setUserMenuAndCache(this, data) {
      const permissionRoutes = getPermissionRoutes(data)
      addRoutes(router, permissionRoutes)
      // 得到详情页isDisplay=false的菜单页
      const noDisplayMenu = getNoDisplayMenuRoutes(permissionRoutes)

      const { menu, cache } = getMenuRoutes([
        ...basicsRoutes,
        ...permissionRoutes
      ])
      this.userMenu = menu
      this.noDisplayMenu = noDisplayMenu
      this.cacheList = cache
    },
    async getUserInfo() {
      console.log('this.oauth.userId', this.oauth, getStorage('userId'))
      const res = await getUserInfoApi({
        id: this.oauth.userId || (getStorage('userId') as number)
      })
      if (res.code === '0000') {
        this.setUserInfo(res.data)
        return true
      } else {
        return false
      }
    },
    // 设置权限
    setOauth(this, data) {
      this.oauth = data
      Object.keys(this.oauth)
        // .filter((item) => item !== 'userId')
        .forEach((key) => setStorage(key, this.oauth[key]))
    },
    setUserDict(this, data) {
      this.dict = data
    },
    loginOut() {
      const tabsStore = useTabsStore()
      Object.keys(this.oauth).forEach((key) => {
        this.oauth[key] = ''
        setStorage(key, '')
      })
      Object.keys(this.userInfo).forEach((key) => (this.userInfo[key] = ''))
      tabsStore.delAllVisitedRoutes()
    },
    async loginOutNetWork() {
      // @Todo: 暂时去掉注销refreshToken
      // if (this.oauth.refreshToken) {
      //   await logout({ refreshToken: this.oauth.refreshToken })
      // }
      this.loginOut()
      useMsg('success', '退出登录成功')
      await router.push({ path: '/login', replace: true })
    },
    async getUserMenu() {
      // @Todo:
      if (!this.userInfo.roleCode) return useMsg('error', '用户未授予角色')
      const res = await getUserMenuApi({
        roleCode: this.userInfo.roleCode
      })
      if (res.code === '0000') {
        console.log('res.data', res.data)
        this.setUserMenuAndCache(res.data)
        this.setUserPermi(res.data)
        return true
      } else {
        return false
      }
    },
    async getUserDict() {
      const res = await allDelDictDataApi()
      if (res.code === '0000') {
        this.setUserDict(res.data)
        return true
      } else {
        return false
      }
    },
    setUserPermi(this, data) {
      const permissionArr: menuItem[] = []
      treeForEach(data, (item) => {
        if (item.funcType == FuncTyp.OPERATION) permissionArr.push(item)
      })
      this.userPermi = permissionArr
    }
  }
})
//菜单页过滤
export function getPermissionRoutes(router: menuModel) {
  console.log('router', router)
  const routes = cloneDeep(router)
  const urlList: string[] = []
  const permissionRoutes = (routes) => {
    const routes_: RouteRecordRaw[] = []
    routes.forEach((route) => {
      const children = route.children
      let component
      if (route.compPath) {
        try {
          Object.keys(viewModules).forEach((key) => {
            if (key.indexOf(route.compPath) > 0) {
              component = viewModules[key]
              return new Error()
            }
          })
        } catch (e) {}
      }
      if (route.compPath && !component)
        console.warn(
          '在src/views/下找不到`' +
            route.compPath +
            '` 或 `' +
            route.compPath +
            '`, 请自行创建!'
        )
      const path = /^\//.test(route.url) ? route.url : `/${route.url}`
      const meta = {
        title: route.funcName,
        icon: route.funcIcon,
        hidden: !route.isDisplay,
        iskeep: route.isCache,
        sort: route.sortOrder,
        funcType: route.funcType,
        breadcrumbHidden: false
      }
      let children_ =
        route.funcType === FuncTyp.CATALOGUE && children && children.length > 0
          ? permissionRoutes(children)
          : []

      if (route.parentId === 0) {
        if (route.funcType == FuncTyp.CATALOGUE) component = layout
        // 一级菜单
        else if (route.funcType == FuncTyp.MENU) {
          children_ = [
            {
              path,
              name: route.compName,
              meta,
              component,
              routeQuery: route.routeQuery
            }
          ]
          component = layout
        }
      } else if (route.funcType == FuncTyp.CATALOGUE) {
        component = null
      }

      if (urlList.some((url) => url === path)) return null
      urlList.push(path)
      routes_.push({
        path:
          route.funcType === FuncTyp.MENU && route.parentId == 0
            ? `${path}Main`
            : path,
        ...(route.funcType === FuncTyp.MENU && {
          name: route.parentId !== 0 ? route.compName : `${route.compName}Main`
        }),
        meta,
        component,
        children: children_,
        routeQuery: route.routeQuery
      })
    })
    return routes_
  }

  return permissionRoutes(routes)
}

export function addRoutes(router: Router, routes: RouteRecordRaw[]) {
  const currenRoutes = router.options.routes
  routes.forEach((route) => {
    const has = currenRoutes.some((item) => item.path == route.path)
    !has && router.addRoute(route)
  })
  const notFound = {
    path: '/:pathMatch(.*)*',
    redirect: '/404'
  }
  router.addRoute(notFound)
}

//菜单页过滤
export function getMenuRoutes(routes: RouteRecordRaw[]) {
  const filterMenu = (routes) => {
    return routes.filter((route) => {
      const children = route.children
      if (children && children.length > 0) {
        route.children = filterMenu(children)
      }
      if (route.meta?.iskeep === true) {
        cache.push(route.name)
      }
      if (route.meta?.hidden === false) {
        return route
      }
    })
  }
  const cache: string[] = []
  const menu = filterMenu(routes)

  return {
    menu,
    cache
  }
}

//得到详情页isDisplay=false的菜单页
export function getNoDisplayMenuRoutes(routes: RouteRecordRaw[]) {
  const routes_: RouteRecordRaw[] = []
  const filterMenu = (routes, parentPath = '') => {
    routes.forEach((route) => {
      const children = route.children
      if (children && children.length > 0) {
        filterMenu(children, route.path)
      }
      if (route.meta?.hidden) {
        routes_.push({ ...route, meta: { ...route.meta, parentPath } })
      }
    })
  }
  filterMenu(routes)
  return routes_
}
